package brad.zimmerman.dungeon.game;

import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.Random;

import android.graphics.PointF;
import android.os.Parcel;
import android.os.Parcelable;



//Holds the current players status
public class ClassGameStats {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public int[][] ritualActions ={
			//This is the amount of curse/piety gained from pre-defined actions
			//k.dead, 	k.living, 	beinghit, hitting, 		hittingtwice, 	killing, 		beingkilled, 	benefits, 	ailments, 	makingwalls, 	destwalls, 		magic, 		glyph dest., buyinggoods, items, 	dodge, bloodpools, potions	magenmy	physenmy
			{-10		,5			,0		,0				,0				,0				,0				,0			,0			,0				,0				,0			,0			,0			,0			,0		,0		,0			,0			,0},
			{0			,0			,0		,0				,0				,5				,0				,0			,0			,0				,0				,0			,0			,0			,0			,-10	,0		,0			,0			,0},
			{0			,0			,0		,0				,0				,0				,0				,0			,0			,5				,-10			,0			,0			,0			,0			,0		,0		,0			,0			,0},
			{0			,0			,-10	,0				,0				,0				,0				,0			,0			,0				,0				,2			,0			,0			,0			,0		,0		,0			,0			,0},
			{0			,0			,0		,2				,0				,0				,0				,0			,0			,0				,0				,0			,0			,0			,0			,0		,5		,-10		,0			,0},
			{0			,0			,0		,0				,0				,-6				,10				,0			,0			,0				,0				,0			,0			,0			,0			,0		,0		,0			,0			,0},
			{5			,-10		,0		,0				,0				,0				,0				,0			,0			,0				,0				,0			,0			,0			,0			,0		,0		,0			,0			,0},
			{0			,0			,0		,2				,0				,0				,0				,0			,0			,0				,0				,-10		,0			,0			,0			,0		,0		,0			,0			,0},
			{0			,0			,0		,0				,-10			,0				,0				,0			,0			,0				,0				,0			,0			,0			,0			,0		,0		,5			,0			,0},
			{0			,0			,2		,0				,0				,0				,-25			,0			,0			,0				,0				,0			,0			,0			,0			,0		,0		,0			,0			,0},
			{0			,0			,0		,0				,0				,0				,0				,-1			,2			,0				,0				,0			,0			,0			,0			,0		,0		,0			,0			,0},
			{0			,0			,0		,0				,0				,0				,0				,0			,0			,0				,0				,-4			,20			,0			,0			,0		,0		,0			,0			,0},
			{0			,0			,0		,0				,0				,0				,0				,0			,0			,0				,0				,2			,-25		,0			,0			,0		,0		,0			,0			,0},
			{0			,0			,0		,0				,0				,0				,0				,0			,0			,0				,0				,0			,0			,0			,0			,0		,0		,0			,-10		,7},
			{0			,0			,0		,0				,0				,0				,0				,0			,0			,0				,0				,0			,0			,0			,0			,0		,0		,0			,7			,-10}


		};
	
	public int player_race;
	public int player_class;
	public int player_level;
	public int player_currenthealth;
	public int player_health;
	public int player_currentmana;
	public int player_mana;
	public int player_attack;
	public int player_gold;
	public int player_hpotions;
	public int player_mpotions;
	public int player_piety;
	public int player_rank;
	public int player_exp;
	public int glyph_quantity;
	public String vicPercentage;
	public int glyphs;
	public int playerSlots;
	public int[] currentGlyphs;
	public int[] spellsUsed;
	public int selectedSpell;
	public boolean extraLife;
	public ClassGlyphActions glyphInfo = new ClassGlyphActions();
	public float attackModifier;
	public float permModifier;
	public float totemBonus;
	public float magicReward;
	public float addToAttackItem;
	public float addToManaItem;
	public float hpKillEvolveRate;
	public boolean hitIncreaseAttack;
	public boolean strikeModifier;
	public boolean manaBurn;
	public boolean poisoned;
	public boolean blinded;
	public boolean weakness;
	public boolean forget;
	public boolean sHub;
	
	public boolean manaBurnImmun;
	public boolean poisonedImmun;
	public boolean blindedImmun;
	public boolean weaknessImmun;
	public boolean forgetImmun;
	public boolean sHUDImmun;
	public boolean noAttackSpells;
	public boolean forHUB;
	
	public int stepsTaken;
	public int bossDead;
	public int playerGod;
	//The primary key for the database
	public int playerID;
	public int playerSight;
	public int renewalRate;
	public int renewalDoubler;
	public int tilesExplored;
	public int eKill;
	public int petraKill;
	public int pDamageTotal;
	public boolean manaRenewal;
	public float physicalResistance;
	public float magicalResistance;
	//Attack bonus for attacking monster of higher level
	public float higherSlaughterBonus;
	//Attack bonus for attacking monster of lower level
	public float lowerSlaughterBonus;
	//Attack bonus for attacking monster of equal level
	public float equalSlaughterBonus;
	public boolean healthy;
	public boolean tricksy;
	public boolean bully;
	public boolean learned;
	public boolean rich;
	public float staticRich;
	public float bloodSucker;
	public float manaBleed;
	public boolean seeGlyphs;
	public boolean seeMonsters;
	public boolean seeItems;
	public boolean manaHeal;
	public boolean desperateBlow;
	public boolean boxerStrength;
	public boolean boxerFatigue;
	public boolean manaRecoil;
	public boolean playerAnger;
	public boolean playerDeathBonus;
	public boolean playerDied;
	public boolean bloodManaBurn;
	public boolean checkBoss;
	public boolean vampireRegen;
	public boolean isKing;
	public boolean manaSparkHalf;
	public int xtraItems;
	public float undeadSlayer;
	public float livingSlayer;
	public float undeadReward;
	public float sickly;
	public float xtraStrength;
	public float dodgeRate;
	public float gamblersLuck;
	public float cautiousLuck;
	public float moreMagic;
	public float shopDiscount;
	public int costModifier;
	public int shopRate;
	public int altarRate;
	public int goldBonus;
	public int killHealth;
	public int killMana;
	public int difficulty;
	public boolean killMaxMana;
	public float glyphBonus;
	public float hPotionRefill;
	public float mPotionRefill;
	public float twiceHit;
	public float enemyStrength;
	public int wallCreateBonus;
	public int wallDestructBonus;
	public int hPotionBonus;
	public int mPotionBonus;
	public boolean opportunistic;
	public boolean alienTeleport;
	public boolean bulldozer;
	public boolean worshipGod;
	public boolean noStores;
	public boolean sharePain;
	public boolean statusMaster;
	public boolean hPotionsDontCure;
	public boolean mPotionsDontCure;
	public boolean superPetrify;
	public boolean hPotions4Mana;
	public boolean exploredFirstStrike;
	public boolean manaAtkUp;
	public boolean buildUp;
	public boolean benefitsPoison;
	public boolean lichAbsorb;
	public boolean attacksPoison;
	public boolean exploredDblHit;
	public boolean seeAltars;
	public boolean attackPoisons;
	public boolean isRobot;
	public boolean makeDifficult;
	public boolean bloodCollector;
	public boolean areaAttack; 
	public boolean allEnemiesCowards;
	public boolean banishImmune;
	public boolean fullHealthImmune;
	public boolean MPHPBonus;
	public boolean unlockedCharacters;
	private boolean specialShops;
	public float bloodCollected;
	public float manaChargedAttack;
	public float benefitsBonus;
	public float buildUpAttack;
	public float adaptationGood;
	public float adaptationBad;
	public float lifeSteal;
	public float hpKillStealRate;
	public float chanceCureAilments;
	public float killPotionChance;
	public float deathGaze;
	public float minerBonus;
	public float attacksAnger;
	public int loseHealthStatBonus;
	public int loseManaStatBonus;
	public int loseHealthStatAilment;
	public int loseManaStatAilment;
	public int deathHealthBonus;
	public int grumpkinLevel;
	public int endingMultiplier;
	public int pietyBonus;
	public float hpSteal;
	public float xtraMana;
	public float chefExp;
	public float enemySightBonus;
	public float enemySightBonusHealth;
	public float totalSightBonusHealth;
	public float totalSightBonus;
	public float totemShamanBonus;
	public float manaRecovered;
	public float mgDmgRecovered;
	public boolean isShaman;
	public int constant;
	public int lastPlayerAttack;
	public int lastEnemyAttack;
	public int lastPlayerMagAttack;
	public int unlockLevel;
	public ClassSoundObjects sounds;
	
	public int[] shopTech;
	public int[] playerTech;
	public int[] backupData;
	
	ClassAnimation shroudAnimations = new ClassAnimation();
	ClassDrawingHolder Draws = new ClassDrawingHolder();

	public int[] objectQuantity = {
			3, //Attack
			8, //Gold
			3, //HP Potions
			3, //Health Up
			3, //Mana Potions
			3  //Mana Up
	};
	ClassDrawingHolder draws = new ClassDrawingHolder();
	
	ClassGameStats(int constant, int player_race, int player_class, int player_level, int [] databaseInfo, ClassSoundObjects sounds, int unlockLevel, int difficulty){
		this.unlockLevel = unlockLevel;
		this.sounds = sounds;
		this.constant = constant;
		this.player_race = player_race;
		this.player_class = player_class;
		this.player_level = player_level;
		this.banishImmune = false;
		this.player_currenthealth = 10;
		this.difficulty = difficulty;
		this.player_currentmana = 10;
		this.player_health = 10;
		this.player_mana = 10;
		this.player_attack = 10;
		this.player_gold = 0;
		this.livingSlayer = 0;
		this.staticRich = 0;
		this.manaChargedAttack = 0;
		this.enemySightBonusHealth = 0;
		this.totalSightBonusHealth = 0;
		this.grumpkinLevel = 1;
		this.glyphBonus = 1;
		this.player_hpotions = 2;
		this.player_mpotions = 2;
		this.shopRate = 3;
		this.altarRate = 3;
		this.player_rank = 1;
		this.player_exp = 0;
		this.player_piety = 0;
		this.lastEnemyAttack = 0;
		this.lastPlayerAttack = 0;
		this.lastPlayerMagAttack = 0;
		this.totemBonus = 0;
		this.addToAttackItem = 0;
		this.wallCreateBonus = 0;
		this.killMaxMana = false;
		this.enemyStrength = 0;
		this.wallDestructBonus = 0;
		this.benefitsBonus = 0;
		this.hpKillEvolveRate = 0;
		this.loseHealthStatBonus = 0;
		this.addToManaItem = 0;
		this.minerBonus = 0;
		this.attacksAnger = 0;
		this.manaBleed = 0;
		this.loseManaStatBonus = 0;
		this.loseHealthStatAilment = 0;
		this.xtraMana = 0;
		this.pietyBonus = 1; 
		this.chanceCureAilments = 0;
		this.hpKillStealRate = 0;
		this.lifeSteal = 0;
		this.hpSteal= 0;
		this.playerGod = 0;
		this.magicReward = 0;
		this.killPotionChance = 0;
		this.deathHealthBonus = 0;
		this.loseManaStatAilment= 0;
		this.vicPercentage = "n/a";
		this.glyph_quantity = 6;
		this.playerSlots = 4;
		this.currentGlyphs = new int[this.playerSlots];
		this.spellsUsed = new int[draws.glyphDescriptions.length];
		for(int i = 0;i< this.currentGlyphs.length;i++){
			this.currentGlyphs[i] = 0;
		}
		for(int i = 0;i< draws.glyphDescriptions.length;i++){
			this.spellsUsed[i] = 0;
		}
		this.attackModifier = (float) 0;
		this.permModifier = 0;
		this.strikeModifier = false;
		this.selectedSpell = -1;
		this.extraLife = false;
		this.hPotions4Mana = false;
		this.exploredFirstStrike = false;
		this.noAttackSpells = false;
		this.manaSparkHalf = false;
		this.benefitsPoison = false;
		this.playerDeathBonus = false;
		this.hitIncreaseAttack = false;
		this.specialShops = false;
		this.sHub = false;
		this.isKing = false;
		this.makeDifficult = false;
		this.isRobot = false;
		this.seeAltars = false;
		this.checkBoss = false;
		this.vampireRegen = false;
		this.stepsTaken = 0;
		this.playerID = (player_class+1) * 100 + (player_level+1);
		this.bossDead = 0;
		this.playerSight = 1;
		this.renewalRate = 1;
		this.renewalDoubler = 0;
		this.totalSightBonus = 0;
		this.manaRecovered = 0;
		this.mgDmgRecovered = 0;
		this.manaBurn = false;
		this.poisoned = false;
		this.forHUB = false;
		this.blinded = false;
		this.weakness = false;
		this.forget = false;
		this.fullHealthImmune = false;
		this.MPHPBonus = false;
		this.manaAtkUp = false;
		this.manaRenewal = false;
		this.playerAnger = false;
		this.hPotionsDontCure = false;
		this.mPotionsDontCure = false;
		this.playerDied = false;
		this.healthy = false;
		this.tricksy = false;
		this.bully = false;
		this.learned = false;
		this.worshipGod = false;
		this.noStores = false;
		this.opportunistic = false;
		this.sharePain = false;
		this.statusMaster = false;
		this.bloodManaBurn = false;
		this.totemShamanBonus = 0;
		this.isShaman = false;
		this.manaBurnImmun = false;
		this.areaAttack = false;
		this.poisonedImmun = false;
		this.blindedImmun = false;
		this.attacksPoison = false;
		this.weaknessImmun = false;
		this.forgetImmun = false;
		this.sHUDImmun = false;
		this.lichAbsorb = false;
		this.rich = false;
		this.allEnemiesCowards = false;
		this.unlockedCharacters = false;
		this.bloodSucker = 0;
		this.seeGlyphs = false;
		this.seeItems = false;
		this.seeMonsters = false;
		this.manaHeal = false;
		this.desperateBlow = false;
		this.alienTeleport = false;
		this.boxerStrength = false;
		this.boxerFatigue = false;
		this.manaRecoil = false;
		this.bulldozer = false;
		this.superPetrify = false;
		this.exploredDblHit = false;
		this.attackPoisons = false;

		this.buildUp = false;
		this.buildUpAttack = 0;
		this.hPotionBonus = 0;
		this.mPotionBonus = 0;
		this.gamblersLuck = 0;
		this.cautiousLuck = 0;
		this.enemySightBonus = 0;
		this.bloodCollector = false;
		this.bloodCollected = 0;
		this.undeadReward = 0;
		this.xtraItems = 0;
		this.tilesExplored = 0;
		this.adaptationBad = 0;
		this.adaptationGood = 0;
		this.eKill=0;
		this.killHealth = 0;
		this.killMana = 0;
		this.petraKill = 0;
		this.pDamageTotal = 0;
		this.deathGaze = 0;
		this.physicalResistance = 0;
		this.magicalResistance = 0;
		this.costModifier = 0;
		this.higherSlaughterBonus = 0;
		this.lowerSlaughterBonus = 0;
		this.twiceHit = 0;
		this.sickly = 0;
		this.dodgeRate = 0;
		this.endingMultiplier = 1;
		this.undeadSlayer = 0;
		this.xtraStrength = 0;
		this.moreMagic = 0;
		this.shopDiscount = 0;
		this.chefExp = 0;
		backupData = new int[] {databaseInfo[0],databaseInfo[1],databaseInfo[2],databaseInfo[3],databaseInfo[4],databaseInfo[5],databaseInfo[6],databaseInfo[7],databaseInfo[8],databaseInfo[9]
				,databaseInfo[10],databaseInfo[11],databaseInfo[12],databaseInfo[13],databaseInfo[14],databaseInfo[15],databaseInfo[16]};
		shopTech = new int[] {databaseInfo[0],databaseInfo[1],databaseInfo[2],databaseInfo[3],databaseInfo[4],databaseInfo[5],databaseInfo[6],databaseInfo[7],databaseInfo[8],databaseInfo[9]};
		playerTech = new int[] {databaseInfo[10],databaseInfo[11],databaseInfo[12],databaseInfo[13],databaseInfo[14],databaseInfo[15],0,databaseInfo[16]};
		this.player_health += playerTech[7];
		this.player_mana += playerTech[7];
		this.player_currenthealth = player_health;
		this.player_currentmana = player_mana;
		this.goldBonus = playerTech[1] * 2;
		objectQuantity[1] += playerTech[0];
		this.mPotionRefill = (float).40 + (float)(.025 * playerTech[2]);
		this.hPotionRefill = (float).40 + (float)(.025 * playerTech[2]);
		this.shopRate += (playerTech[4]+1)/2;
		this.altarRate += (playerTech[4]+1)/3;
		this.shopDiscount += (.05) * playerTech[3];
		//playerTech[5] = 10;
		//playerTech[7] = 10;
		System.out.println("Character Created : " + player_class);
		classSkills(this.player_class);
		System.out.println("Character Created : " + player_class);
		//holder = "Increases shop frequency by " + ((this.techlevel)+1)/2 + "% permanently\n";
		//holder += "Increases altar frequency by " + ((this.techlevel)+1)/3 + "% permanently";
		
	}
	
	public void pietyActions(int action){
		if(this.worshipGod){
			this.player_piety += ritualActions[this.playerGod-1][action] * this.pietyBonus;
			if (this.player_piety < -20){
				this.player_piety = -20;
			}
		}
	}
	
	public void calcPiety(int godApproval){
		this.player_piety += godApproval;
	}
	
	public void updateTotemBonus(float countedTotems){
		if(isShaman){
			totemShamanBonus = 2* countedTotems;
		}
		totemBonus = (5 * countedTotems)/100;
	}
	
	public boolean useHealthPotion(){
		if(!this.isRobot){
		if(((this.player_currenthealth < getPlayerMaxHealth()) || this.poisoned || this.blinded || this.weakness)&&this.player_hpotions>0){
			this.player_hpotions--;
			pietyActions(17);
			if (!this.hPotionsDontCure){
				this.poisoned = false;
				this.blinded = false;
				this.weakness = false;
			}
			if(!this.didItHit((int)(this.chefExp * 100), 100)){
				this.addEXP(this.player_rank);
			}
			this.player_currenthealth += getPlayerMaxHealth() * this.hPotionRefill;
			if (this.player_currenthealth > getPlayerMaxHealth()){
				this.player_currenthealth = getPlayerMaxHealth();
			}
			if (this.hPotions4Mana){
				this.player_currentmana += getPlayerMaxMana() * this.mPotionRefill;
        		if (this.player_currentmana > getPlayerMaxMana()){
        			this.player_currentmana = getPlayerMaxMana();
        		}
			}
			return true;
		}
		return false;
		}else if(player_hpotions>0){
			this.player_gold += this.player_rank * 5;
			this.player_hpotions--;
			return true;
		}
		return false;
	}
	
	public void applyExploredBonus(boolean explored){
		if (explored){
			if (this.exploredFirstStrike){
				this.strikeModifier = true;
			}
		}
	}
	
	public boolean useManaPotion(){
		if(!this.isRobot){
			if(((this.player_currentmana < getPlayerMaxMana()) || this.sHub || this.manaBurn || this.forget)&&this.player_mpotions>0){
				this.player_mpotions--;
				pietyActions(17);
				if (!this.mPotionsDontCure){
					this.manaBurn = false;
					this.forget = false;
					this.sHub = false;
				}
				if(!this.didItHit((int)(this.chefExp * 100), 100)){
					this.addEXP(this.player_rank);
				}
				this.player_currentmana += getPlayerMaxMana() * this.mPotionRefill;
				if (this.player_currentmana > getPlayerMaxMana()){
					this.player_currentmana = getPlayerMaxMana();
				}
				if (this.manaAtkUp){
					this.attackModifier = (float) .30;
				}
				return true;
			}
			return false;
		}else if(player_mpotions>0){
			this.player_gold += this.player_rank * 5;
			this.player_mpotions--;
			return true;
		}
		return false;
	}
	
	public void classSkills(int pClass){
		
		switch(pClass){
			case 0://"Acolyte",
				this.seeAltars = true; this.magicalResistance = (float) 0.25; this.physicalResistance = (float) -0.25; this.pietyBonus = 2; break;
			case 1://"Alien",
				this.currentGlyphs[0] = 15; this.alienTeleport = true; this.mPotionRefill = 1; this.hPotions4Mana = true; break;
			case 2://"Archeologist",
				this.currentGlyphs[0] = 4;this.minerBonus = 1;this.bloodCollector=true;break;
			case 3://"Assassin",
				this.currentGlyphs[0] = 12; this.bully = true; this.chanceCureAilments += (float) .02;/*this.exploredFirstStrike = true;*/ break;
			case 4://"Beastmaster",
				this.grumpkinLevel = 2; this.currentGlyphs[0] = 7; this.poisonedImmun = true; break;
			case 5://"Berserker",
				this.glyph_quantity--;this.magicalResistance = (float) 0.5; 
			this.permModifier = (float) 0.5; this.costModifier = 2; this.higherSlaughterBonus = (float) .25; break;
			case 6://"Blademaster",
				addToAttackItem = 4; areaAttack = true; this.weaknessImmun = true; break;
			case 7://"Bloodmage",
				this.currentGlyphs[0] = 1; this.mPotionRefill = 1; this.bloodSucker = (float) .10; break;
			case 8://"Boxer",
				this.boxerStrength = true; this.boxerFatigue = true; this.seeMonsters = true; break;
			case 9://"Chef",
				this.killPotionChance = (float) .1; chefExp = (float) .1; break;
			case 10://"Crusader",
				this.poisonedImmun = true; this.manaBurnImmun = true; this.buildUp = true; this.playerDeathBonus = true; break;
			case 11://"Dragon",
				this.playerSight = 2; this.sickly = -10; this.player_health *= 2; this.player_currenthealth *= 2; this.noAttackSpells = true; break;
			case 12://"Earl",
				this.moreMagic =(float) .25; this.rich = true; this.player_mana += 5; this.player_currentmana += 5; break;
			case 13://"Escape Artist",
				mPotionRefill = (float) (mPotionRefill*0.45);hPotionRefill= (float) (hPotionRefill*0.45);sHUDImmun = true;banishImmune = true;
			manaRecovered = (float) 0.1; fullHealthImmune = true;/*Cannot die with full health*/break;
			case 14://"Fighter",
				this.learned = true; this.extraLife = true; this.opportunistic = true; break;
			case 15://"Forrester",
				this.poisonedImmun = true; this.manaBurnImmun = true; this.exploredDblHit = true; this.playerSight = 2; break;
			case 16://"Gambler",
				this.gamblersLuck = (float) .1; this.blindedImmun = true; this.exploredFirstStrike = true; break;
			case 17://"Gorgon",
				this.permModifier = (float) - 0.50; this.physicalResistance = (float) 0.5; this.poisonedImmun = true; this.manaBurnImmun = true; 
			this.killMana += 2; this.currentGlyphs[0] = 4; this.deathGaze += .1; break;
			case 18://"Jester",
				this.dodgeRate = (float) .20; this.permModifier = (float) -.5; this.attacksPoison = true; break;
			case 19://"Juggler",
				this.poisonedImmun = true; this.manaBurnImmun = true; this.weaknessImmun = true; this.forgetImmun = true; 
			this.blindedImmun = true; this.sHUDImmun = true; this.moreMagic = (float) .3; this.altarRate = 0; break;
			case 20://"King",
				this.magicalResistance = (float) 0.25; this.isKing = true; this.shopDiscount += .5; break;
			case 21://"Lich",
				this.xtraMana = -5; this.xtraStrength = -5; this.sickly = 10; this.lichAbsorb = true; break;
			case 22://"Marauder",
				this.permModifier = (float) 1; this.tricksy = true; attacksAnger = (float) .25; this.allEnemiesCowards = true; break;
			case 23://"MinuteMan",
				this.permModifier = (float) -.16; this.enemySightBonus = (float) .08; break;
			case 24://"Monk",
				this.magicalResistance = (float) 0.5; this.physicalResistance = (float) 0.5; this.permModifier = (float) - 0.5; this.seeMonsters = true; /*this.healthy = true;*/ break;
			case 25://"Paladin",
				this.magicReward = (float) .5; this.currentGlyphs[0] = 8; this.magicalResistance = (float) 0.25; break;
			case 26://"Peasant",
				this.permModifier = (float) -.5; this.moreMagic = (float) -.5;  this.shopDiscount += .5; endingMultiplier = 4; break;
			case 27://"Priest",
				this.sickly = -2; this.hPotionRefill = 1; this.undeadSlayer = 2; break;
			case 28://"Princess"
				this.currentGlyphs[0] = 20;
				this.specialShops = true;
				break;
			case 29://"Prog Master",
				this.shopRate+=2;this.shopDiscount=1;this.endingMultiplier = 8; this.makeDifficult = true;break;
			case 30://"Racer",
				this.manaSparkHalf = true; this.xtraMana = 5; this.mPotionRefill = 1; break;
			case 31://"Robot",
				this.magicalResistance = (float) 0.5; this.physicalResistance = (float) 0.5;this.poisonedImmun = true; this.manaBurnImmun = true; this.weaknessImmun = true; this.forgetImmun = true; 
			this.blindedImmun = true; this.sHUDImmun = true; this.isRobot=true; this.sickly = -3; break;
			case 32://"Rogue",
				this.tricksy = true; this.permModifier = (float) 0.5; this.sickly = 5; this.twiceHit = (float) .10; this.dodgeRate = (float) .10; this.player_health -= 5; this.player_currenthealth -=5; break;
			case 33://"Scientist",
				this.poisonedImmun = true; this.xtraMana = 2; this.sickly = 10; this.enemySightBonusHealth = 5;break;
			case 34://"Shaman",
				this.currentGlyphs[0] = 17; this.undeadSlayer = (float) -.25; this.livingSlayer = (float) .25; this.isShaman = true;break;
			case 35://"Sorcerer",
				this.manaRecoil = true; this.manaHeal = true; this.player_mana += 5; this.player_currentmana += 5; break;
			case 36://"Soul Eater",
				this.hitIncreaseAttack = true; this.xtraMana = -5; this.xtraStrength = -5; this.player_mana = 0; this.player_currentmana = 0; 
			this.addToManaItem = -5; this.player_attack = 0; this.player_hpotions += 2; this.player_mpotions -= 2; break;
			case 37:
				//"Sultan"
				this.poisonedImmun = true;
				this.weaknessImmun = true; 
				this.forgetImmun = true; 
				this.blindedImmun = true;
				this.staticRich = 20;
				break;
			case 38://"Swindler",
				this.sickly = 5; this.xtraMana = 5; MPHPBonus = true; break;
			case 39://"Tempest",
				this.moreMagic = (float) .8; mgDmgRecovered = (float) .1; manaBleed = (float) -.08; break;
			case 40://"Thief",
				this.mPotionRefill = 1; this.hPotionRefill = 1; this.xtraItems = 1; this.equalSlaughterBonus += .5; break;
			case 41://"Tinker",
				this.rich = true; this.shopRate += 6; this.shopDiscount += .20; break;
			case 42://"Transmuter",
				this.currentGlyphs[0] = 4; this.bulldozer = true; this.wallDestructBonus += 2; banishImmune = true; break;
			case 43:
				//Traveller
				this.banishImmune = true;
				this.sHUDImmun = true;
				this.manaBurnImmun = true;
				manaChargedAttack = 1.5f;
				break;
			case 44://"Vampire",
				this.vampireRegen = true; this.xtraStrength = 2; this.poisonedImmun = true; this.blindedImmun = true; this.tricksy = true; 
			this.bloodSucker = (float) .10; this.lifeSteal = (float) .05; break;
			case 45://"Warlord",
				this.currentGlyphs[0] = 9; this.desperateBlow = true; this.manaAtkUp = true; break;
			case 46://"Werebear",
				this.player_health *= 4; this.player_currenthealth *= 4; this.mPotionRefill = 1; this.hPotionRefill = 1; this.renewalRate = 0; break;
			case 47://"Wizard"
			this.moreMagic = (float) .3;this.permModifier = (float) - 0.30; this.costModifier = -1; this.seeGlyphs = true; /*this.glyph_quantity++;*/ break;
			default: break;
		}

	}
	
	public void stepTaken(){
		if(this.renewalDoubler > 0){
			this.renewalDoubler--;
		}
	}
	
	public int findMax(int[] array){
		//Finds the max in an array and returns it
		int max = 0;
		for(int i = 0; i < array.length; i++){
			//System.out.println(max + " " + array[i]);
			if(max < array[i]){
				max = array[i];
			}
		}
		if (max == 0){
			max = -1;
		}
		return max;
	}
	
	
	
	public String printSpells(int usage, int[] array){
		//Finds all of the locations in an array with a certain value and concatenates strings
		String holder = "";
		if(usage == -1){
			holder = "No Spells Used";
		}else{
		for(int i = 0; i < array.length; i++){
			if(usage == array[i]){
				holder += draws.glyphStrings[i] + " ";
			}
		}
		holder += " (" + usage + ") ";
		}
		return holder;
	}
	
	public int nextLvlExp(int exp){
		int i = 1;
		while(((i*i)*1000 + i*1000)< exp){
			i++;
		}
		return ((i*i)*1000 + i*1000);
	}
	
	public String rankTitle(){
		return "Level " + player_rank + " " + draws.raceStrings[player_race] + " " + draws.classStrings[player_class]+"\n";
	}
	
	public String playerLeft(){
		String info = "";
		info += "Exp:\n";
		info +=	"Kills:\n";
		info +=	"Damage:\n";
		info += "Steps:\n";
		info +=	"Explored:\n";
		info +=	"Petrified:\n";
		info += "Score:\n";
		
		return info;
	}
	
	public String playerRight(){
		String info = "";
		info += (player_exp + player_rank*5)+ "\n";
		info +=	this.eKill + "\n";
		info +=	this.pDamageTotal + "\n";
		info += stepsTaken + "\n";
		info +=	this.tilesExplored + "\n";
		info +=	this.petraKill + "\n";
		info += this.calculateScore() + "\n\n\n";
		
		return info;
	}
	
	public int calculateScore(){
		int calculation = 0;
		calculation += this.pDamageTotal *3;
		calculation += this.bossDead * 3500;
		calculation += this.tilesExplored * 4;
		calculation += this.eKill * 100;
		calculation += this.petraKill * 250;
		calculation += this.player_rank * 300 + 20 * (this.player_rank * this.player_rank);
		calculation *= ((float)Draws.levelDifficulty[this.player_level]/(float)10) * (((float)this.difficulty+50) / 100);
		return calculation;
	}
	
	public String playerBottom(){
		String info = "";
		info += "Fav Spell: \n" + printSpells(findMax(this.spellsUsed),this.spellsUsed) + "\n";
		
		return info;
	}
	
	public void levelUp(){
		while(this.player_exp>=this.player_rank*5){
			for(int i =((constant*6)+3); i < ((constant*13)-3); i+=5){
				this.shroudAnimations.addKillBubbles(i, (((27)* constant) + (3*constant)/4)+3, 0,true);
			}
			this.player_health += (10 - this.sickly);
			this.player_mana += 5 + this.xtraMana;
			this.player_exp =  this.player_exp - ((this.player_rank)*5);
			this.player_rank ++;
			this.player_attack += 5 + this.xtraStrength;
			this.player_currenthealth = getPlayerMaxHealth();
			this.player_currentmana = getPlayerMaxMana();
			this.manaBurn = false;
			this.poisoned = false;
			this.blinded = false;
			this.forget = false;
			this.weakness = false;
			this.sHub = false;
		}
	}
	
	public boolean addEXP(int exp){
		boolean leveledUp = false;
		this.player_exp += exp;
		if (this.player_exp >= this.player_rank*5 && this.player_rank < 10){
			levelUp();
			leveledUp = !leveledUp;
		}
		else if (this.player_rank == 10 && this.player_exp > this.player_rank*5 ){
			this.player_exp = this.player_rank*5;
		}
		return leveledUp;
	}
	
	//This is for the final scoring to determine what gets to go into the database and what doesn't
	public int[] determineGreater(int hRank, int hScore, int hStepsTaken, int hCompleted){
		int[] holder = new int[4];
		if(this.player_rank > hRank){holder[0] = this.player_rank;}
		else{holder[0] = hRank;}
		if(this.calculateScore()>hScore){holder[1] = this.calculateScore();}
		else{holder[1] = hScore;}
		if(this.stepsTaken<hStepsTaken){holder[2] = this.stepsTaken;}
		else{holder[2] = hStepsTaken;}
		if(this.checkBoss){holder[3] = 1;}
		else{holder[3] = hCompleted;}
		return holder;
	}
	
	public int returnRenewalRate(boolean forMana){
		if(this.renewalDoubler > 0 || this.healthy){
			if(bulldozer && !forMana){
				return 0;
			}else{
				return this.renewalRate*2;
			}
		}
		else{
			if(bulldozer && !forMana){
				return 0;
			}else{
				return this.renewalRate;
			}
		}
	}
	
	public boolean playerNumber(int number){
		switch(number){
		case 0:return this.manaBurn;
		case 1:return this.poisoned;
		case 2:return false;
		case 3:return false;
		case 4:return false;
		case 5:return false;
		case 6:return this.forget;
		case 7:return this.blinded;
		case 8:return this.weakness;
		case 9:return false;
		case 10:return false;
		case 11:return false;
		case 12:return this.extraLife;
		case 13:return this.firstStrike();
		case 14:return false;
		case 15:return false;
		case 16:return this.sHub;
		default: return false;
		}
	}
	
	public int getPlayerMaxHealth(){
		return (int) (this.player_health + this.totalSightBonusHealth + this.totemShamanBonus);
	}
	
	public int getPlayerMaxMana(){
		return (int) (this.player_mana + this.totemShamanBonus);
	}
	
	//This is after the enemy is killed
	public boolean killCalc(int enemyLVL, boolean Undead, boolean magicUser){
		boolean leveledUp = false;
		if (enemyLVL == 10){
			sounds.playSound(12);
		}else{
			sounds.playSound(4);
		}
		pietyActions(5);
		this.eKill++;
		this.player_currenthealth = this.addHealth(this.player_currenthealth, getPlayerMaxHealth(), (int) (this.hpKillStealRate * getPlayerMaxHealth()));
		this.player_health += this.hpKillEvolveRate;
		if(!didItHit((int)(100*this.killPotionChance),100)){
			Random random = new Random(System.currentTimeMillis());
			int chance = random.nextInt( 2 );
			switch(chance){
				case 0:this.player_hpotions++;
				case 1:this.player_mpotions++;
				default:this.player_hpotions++;
			}
		}
		if (this.buildUp){
			this.buildUpAttack += (float) .10;
		}
		if (enemyLVL == 10){
			this.bossDead++;
			this.checkBoss = true;
		}
		if (this.rich){
			this.player_gold += enemyLVL;
		}
		this.player_gold += staticRich;
		if (magicUser){
			pietyActions(18);
			this.player_currenthealth = this.addHealth(this.player_currenthealth, getPlayerMaxHealth(), (int) (getPlayerMaxHealth() * this.magicReward));
		}else{
			pietyActions(19);
		}
		if (Undead){
			pietyActions(0);
			this.player_currenthealth = this.addHealth(this.player_currenthealth, getPlayerMaxHealth(), (int) (getPlayerMaxHealth() * this.undeadReward));
		}else{
			pietyActions(1);
		}
		if (this.learned){
			this.player_exp += 1;
		}
		if (opportunistic){
			this.strikeModifier = true;
		}
		
		this.player_exp += experienceBonus(this.player_rank,enemyLVL);
		this.player_currenthealth += this.killHealth;
		this.player_currentmana += this.killMana;
		this.player_currentmana += this.manaRecovered * getPlayerMaxMana();
		if(this.killMaxMana){
			if(this.player_currentmana> 1){
				this.player_currentmana = (int) (player_currentmana * .5);
			}
		}
		if (this.player_currentmana > getPlayerMaxMana()){
			this.player_currentmana = getPlayerMaxMana();
		}

		//To make sure that the player cannot make it past lvl 10
		if (this.player_exp >= this.player_rank*5 && this.player_rank < 10){
			levelUp();
			leveledUp = !leveledUp;
		}else if (this.player_rank == 10 && this.player_exp > this.player_rank*5 ){
			this.player_exp = this.player_rank*5;
		}
		return leveledUp;
	}
	
	//Used to calculate the amount of health lost for the player
	public int enemyStrike(ClassEnemyStats enemy){
		float enemyAttack = enemy.attack;
		
		enemyAttack = enemyAttack * (1 - enemyStrength);
		
		if (!enemy.magicAttack){enemyAttack = enemyAttack * (1 - this.physicalResistance);}
		else{enemyAttack = enemyAttack * (1 - this.magicalResistance);}
		
		if (enemyAttack> this.player_currenthealth){
			enemyAttack = this.player_currenthealth;
		}
		
		if (enemyAttack <= 0){enemyAttack = 1;}
		
		return (int) enemyAttack;
	}
	
	//This function is used to predict the amount of health lost for the enemy
	public int playerStrike(ClassEnemyStats enemy,boolean prediction){
		float playerAttack;
		float multiplier = 0;
		float attackHolder = this.returnAttack();
		
		if(this.MPHPBonus){
			int bonus = player_mana - player_health;
			if (bonus > 0){
				attackHolder += bonus;
			}
		}
		if(staticRich > 0){
			attackHolder += this.player_gold * 2.5;
		}
		if(manaChargedAttack > 0){
			attackHolder += player_currentmana * manaChargedAttack;
		}
		if((this.gamblersLuck  != 0 || this.cautiousLuck != 0)&&(!prediction)){
			attackHolder = gamblerAttack(attackHolder, this.gamblersLuck, this.cautiousLuck);
		}
		if(this.playerDeathBonus && this.playerDied){
			attackHolder*=4;
		}
		if (this.buildUp){
			attackHolder += attackHolder * this.buildUpAttack;
		}
		if((this.weakness || this.blinded || this.forget || this.poisoned || this.manaBurn) && (adaptationBad != 0))
		{attackHolder += attackHolder * adaptationBad;}
		if((this.desperateBlow) && (this.player_currenthealth < this.getPlayerMaxHealth()/4))
		{attackHolder += attackHolder * .75;}
		
		if((this.undeadSlayer != 0) && (enemy.undead)){attackHolder += attackHolder * this.undeadSlayer;}
		if((this.livingSlayer != 0) && (!enemy.undead)){attackHolder += attackHolder * this.livingSlayer;}
		
		if ((enemy.level > this.player_rank) && (this.higherSlaughterBonus != 0)){attackHolder *= 1 + this.higherSlaughterBonus;}
		else if ((enemy.level == this.player_rank) && (this.equalSlaughterBonus != 0)){attackHolder *= 1 + this.equalSlaughterBonus;}
		else if ((enemy.level < this.player_rank) && (this.lowerSlaughterBonus != 0)){attackHolder *= 1 + this.lowerSlaughterBonus;}
		
		if (this.weakness){multiplier += .25;}
		if (enemy.PRnorm){multiplier += .25;}
		if (enemy.PRplus){multiplier += .50;}
		
		playerAttack = attackHolder * (1 - multiplier);
		
		if (this.bully && (enemy.level < this.player_rank)){
			playerAttack = enemy.currentHealth;
		}
		if (!forHUB){
		if (playerAttack> enemy.currentHealth){
			playerAttack = enemy.currentHealth;
		}
		}
		
		if (playerAttack <= 0){playerAttack = 1;}
		
		return (int) playerAttack;
	}
	
	//This is the predicted outcome
	public int calcWin(ClassEnemyStats enemy, boolean exploredAround){
		float playerAttack;
		float enemyAttack;
		////applyExploredBonus
		playerAttack = playerStrike(enemy,true);
		enemyAttack = enemyStrike(enemy);
		
		if (
    			((this.player_currenthealth > enemyAttack) && (playerAttack >= enemy.currentHealth) && (enemy.extraLives < 2))
    			||
    			((playerAttack >= enemy.currentHealth) && ((this.firstStrike()||(exploredAround && this.exploredFirstStrike)) && !enemy.fStrike)
    					&& (enemy.extraLives < 2) && ! this.blinded)
    		){
    		return 1;
    	}else if (this.player_currenthealth>enemyAttack || (this.player_currenthealth<=enemyAttack && this.extraLife)){
    		return 0;
    	}else{
    		return -1;
    	}
    }
	
	public void curePlayerAilments(){
		if(this.poisoned){
			if(!this.didItHit((int) (100 * this.chanceCureAilments), 100)){
				this.poisoned = false;
			}
		}
		if(this.manaBurn){
			if(!this.didItHit((int) (100 * this.chanceCureAilments), 100)){
				this.manaBurn = false;
			}
		}
		if(this.blinded){
			if(!this.didItHit((int) (100 * this.chanceCureAilments), 100)){
				this.blinded = false;
			}
		}
		if(this.forget){
			if(!this.didItHit((int) (100 * this.chanceCureAilments), 100)){
				this.forget = false;
			}
		}
		if(this.weakness){
			if(!this.didItHit((int) (100 * this.chanceCureAilments), 100)){
				this.weakness = false;
			}
		}
	}
	
	public boolean didItHit(int odds, int outOf){
		Random random = new Random(System.currentTimeMillis());
		//false means that the odds hit
		return (odds-1) < (random.nextInt( outOf ));
	}
	
	public ClassEnemyStats playerTakingDamage(ClassEnemyStats enemy, int enemyAttack){
		this.player_currenthealth -= enemyAttack;	
		lastEnemyAttack = enemyAttack;
		if (this.hpSteal !=0){
			player_currenthealth = this.addHealth(player_currenthealth, getPlayerMaxHealth(), (int)(hpSteal * player_rank));
		}
		if (this.sharePain){
			player_currentmana = this.addHealth(player_currentmana, getPlayerMaxMana(), (int)-enemyAttack);
		}
		
		if (this.manaRecoil){
			enemy.currentHealth -= this.player_rank;
			if(enemy.currentHealth<0){
				enemy.currentHealth = 0;
			}
		}
		if(enemy.poison && !this.poisonedImmun){
			pietyActions(8);
			this.poisoned = true;
		}
		if(enemy.mburn && !this.manaBurnImmun){
			pietyActions(8);
			this.manaBurn = true;
		}
		if(enemy.blind && !this.blindedImmun){
			pietyActions(8);
			this.blinded = true;
		}
		if(enemy.forget && !this.forgetImmun){
			pietyActions(8);
			this.forget = true;
		}
		if(enemy.weakness && !this.weaknessImmun){
			pietyActions(8);
			this.weakness = true;
		}
		if(enemy.sHUD && !this.sHUDImmun){
			pietyActions(8);
			this.sHub = true;
		}
		return enemy;
	}
	
	public ClassEnemyStats enemyTakingDamage(ClassEnemyStats enemy, int playerAttack){
		this.pDamageTotal += playerAttack;
		//System.out.println(this.pDamageTotal);
		enemy.currentHealth -= playerAttack;
		lastPlayerAttack = playerAttack;
		//If the player is stealing health
		if(this.lifeSteal != 0){
			//Take health away from enemy
			enemy.currentHealth = this.addHealth(enemy.currentHealth, enemy.health, (int)(-playerAttack * this.lifeSteal));
			//Give health to player
			this.player_currenthealth = this.addHealth(this.player_currenthealth, getPlayerMaxHealth(), (int)(playerAttack * this.lifeSteal));
			//If too much health is stolen...
			if (enemy.currentHealth < 0){
				//Take health away from player
				this.player_currenthealth = this.addHealth(this.player_currenthealth, getPlayerMaxHealth(), (int)enemy.currentHealth);
				//Set enemy health to 0
				enemy.currentHealth = 0;
			}
		}
		if(this.boxerStrength){
			this.permModifier += (float).12;
		}
		if(this.attacksPoison || this.attackPoisons){
			enemy.ePoisoned = true;
		}
		return enemy;
	}
	
	//This is the actual fight
	public ClassEnemyStats calculateDamage(ClassEnemyStats enemy, boolean exploredAround, float strength){
		//fullHealthImmune
		if(!this.isRobot || (this.isRobot && this.player_gold>0)){
			if(this.isRobot){
				this.player_gold--;
			}
		float playerAttack;
		float enemyAttack;
		boolean playerHIT = false;
		boolean playerAtFullHealth = (player_currenthealth == getPlayerMaxHealth());
		float benBonus = 0;
		this.applyExploredBonus(exploredAround);
		this.lastEnemyAttack = 0;
		this.lastPlayerAttack = 0;
		enemy.ePoisoned = false;
		
		if(this.hasGoodEffects()){
			benBonus = this.benefitsBonus;
		}
		if(this.exploredDblHit && exploredAround){
			benBonus = (float) .3;
		}
		
		playerAttack = 1;
		enemyAttack = 1;
		
		if (this.firstStrike() && !enemy.fStrike){
			this.lastEnemyAttack = -1;
			//Strike first if first strike
			if(!this.blinded || didItHit(1,10)){
				playerAttack = playerStrike(enemy,false) * strength;
				enemy = this.enemyTakingDamage(enemy,(int)playerAttack);
				if(this.hitIncreaseAttack){
					this.player_attack += 1;
				}
				pietyActions(3);
				if (!didItHit((int)(100 * (this.twiceHit + benBonus)),100)){
					playerAttack = playerStrike(enemy,false) * strength;
					pietyActions(3);
					pietyActions(4);
					enemy = this.enemyTakingDamage(enemy, (int)playerAttack);
					if(this.hitIncreaseAttack){
						this.player_attack += 1;
					}
				}
			}
			//If the enemy is still alive and player doesn't dodge, they get to hit back
			if(enemy.currentHealth>0 || enemy.extraLives>1){
				if(didItHit((int)(100 * (this.dodgeRate + benBonus)),100)){
					enemyAttack = enemyStrike(enemy);
					enemy = this.playerTakingDamage(enemy, (int) enemyAttack);
					pietyActions(2);
					playerHIT = true;
				}else{
					pietyActions(15);
					this.lastEnemyAttack = 0;
				}
			}
		}
		else{
			//The player has to go first due to the chance that the enemy might blind the player and 
			//the player might miss the next attack without explanation
			if(!this.blinded || didItHit(1,10)){
				playerAttack = playerStrike(enemy,false) * strength;
				pietyActions(3);
				enemy = this.enemyTakingDamage(enemy,(int)playerAttack);
				if(this.hitIncreaseAttack){
					this.player_attack += 1;
				}
				if (!didItHit((int)(100 * (this.twiceHit + benBonus)),100)){
					playerAttack = playerStrike(enemy,false) * strength;
					pietyActions(3);
					pietyActions(4);
					enemy = this.enemyTakingDamage(enemy, (int) playerAttack);
				}
			}
			//If there is no first strike, the enemy and hero hit at the same time
			if(didItHit((int)(100 * (this.dodgeRate + benBonus)),100)){
				enemyAttack = enemyStrike(enemy);
				enemy = this.playerTakingDamage(enemy, (int) enemyAttack);
				pietyActions(2);
				playerHIT = true;
			}else{
				//Player Dodged
				pietyActions(15);
			}
		}
		this.doneAttacking();
		if (this.playerAnger && playerHIT){
			this.attackModifier = (float) .30;
		}
		if(enemy.currentHealth > 0){
			this.buildUpAttack = 0;
		}
		//The enemy has been petrified
		if(!this.didItHit((int)(100 * this.deathGaze),100) && enemy.currentHealth> 0 && enemy.level<=8){
			enemy.petrified = true;
		}
		if(playerAtFullHealth && fullHealthImmune && player_currenthealth< 1){
			player_currenthealth = 1;
		}
	}
		return enemy;
	}
	
	public float gamblerAttack(float Attack, float luck, float cLuck){
		float lowerBound = 0;
		float upperBound = 0;
		if (luck > 0 && cLuck == 0){
			lowerBound = (float) (Attack * .7);
			upperBound = (float) (Attack * (1+luck));
		}
		else if (luck == 0 && cLuck > 0){
			lowerBound = (float) (Attack);
			upperBound = (float) (Attack * (1+cLuck));
		}
		else if (luck > 0 && cLuck > 0){
			lowerBound = (float) (Attack * .7);
			upperBound = (float) (Attack * (1+luck+cLuck));
		}
		float actualBonus;
		Random random = new Random(System.currentTimeMillis());
		int percentAttack = random.nextInt( 100 )+1;
		actualBonus = (upperBound-lowerBound) * (percentAttack/100);
		return (lowerBound + actualBonus);
	}
	
	public int returnAttack(){
		return (int) (this.player_attack + this.player_attack * (attackModifier + permModifier + totalSightBonus+totemBonus));
	}
	
	public boolean firstStrike(){
		return (this.strikeModifier||this.tricksy);
	}
	
	//This implements the cleanup phase after the player is finished attacking
	public void doneAttacking(){
		if(staticRich > 0){
			this.player_gold /= 2;
		}
		if(manaChargedAttack > 0){
			player_currentmana/=2;
		}
		this.attackModifier = 0;
		this.strikeModifier = false;
		this.playerDied = false;
		this.attackPoisons = false;
	}
	
	public void updateVic(String update){
		this.vicPercentage = update;
	}
	public int addGlyph(int glyph){
		for(int i = 0;i< this.currentGlyphs.length;i++){
			if (this.currentGlyphs[i] == 0){
				this.currentGlyphs[i] = glyph+1;
				return 1;
			}
		}
		//returns if there are no spaces left
		return -1;
	}
	
	public int removeGlyph(int glyph){
		for(int i = 0;i< this.currentGlyphs.length;i++){
			if (this.currentGlyphs[i] == glyph+1){
				this.currentGlyphs[i] = 0;
				return 1;
			}
		}
		//returns if there are no glyphs that match the desired glyph
		return -1;
	}
	
	//Returns the cost of a glyph in the players inventory
	public int returnCost(int glyph){
		return glyphInfo.returnCost(glyph,this);
	}
	
	public int returnOffense(int glyph){
		return glyphInfo.offenseSpells(glyph);
	}
	
	public int experienceBonus(int pLevel, int eLevel){
    	int holder = eLevel - pLevel;
    	if (holder <=0){holder = 0;}
    	switch(holder){
    		case 1:return eLevel + 2; 
    		case 2:return eLevel + 6;
    		case 3:return eLevel + 12;
    		case 4:return eLevel + 20;
    		case 5:return eLevel + 30;
    		case 6:return eLevel + 42;
    		case 7:return eLevel + 56;
    		case 8:return eLevel + 72;
    		case 9:return eLevel + 90;
    		default: return eLevel;
    	}
    }
	
	public void trashGlyph(){
		if(this.gamblersLuck != 0){
			this.gamblersLuck += .2;
		}
		if (this.lifeSteal > 0){
			this.lifeSteal += (float) .05;
		}
		if (this.deathGaze > 0){
			this.deathGaze += (float) .05;
		}
		pietyActions(12);
		switch(this.player_race){
			case 0: this.player_health += 10 * this.glyphBonus; break;
			case 1: this.player_hpotions += 1 * this.glyphBonus; break;
			case 2: this.player_mana += 10 * this.glyphBonus; break;
			case 3: this.player_mpotions += 1  * this.glyphBonus; break;
			case 4: this.permModifier += .10 * this.glyphBonus; break;
			case 5: this.player_gold += 10 * this.glyphBonus; break;
			case 6: this.addEXP((int)(5* this.glyphBonus)); break;
			case 7: this.twiceHit += .05 * this.glyphBonus; break;
			case 8: this.player_attack += 5 * this.glyphBonus; break;
			default:break;
		}
	}
	
	public int returnSight(){
		//if(this.blinded){
		//	return 1;
		//}
		//else{
		return this.playerSight;
		//}
	}
	
	public void shroudRenewal(int playerX, int playerY){
		int differenceA, differenceB;
		if(!this.poisoned && !this.manaRenewal){
				differenceA = this.player_currenthealth;
				if(!this.vampireRegen){
					this.player_currenthealth = this.addHealth(this.player_currenthealth, getPlayerMaxHealth(), returnRenewalRate(false) * this.player_rank);
				}else{
					this.player_currenthealth = this.addHealth(this.player_currenthealth, getPlayerMaxHealth(), -1 * this.player_rank);
					if(this.player_currenthealth<=0){
						this.player_currenthealth = 1;
					}
				}
				differenceB = this.player_currenthealth;
				if (differenceA!= differenceB){
					shroudAnimations.addAnimatedShroud((playerX+1)*constant, (playerY+1)*constant, 1);
				}
		}
		if(!this.manaBurn){
			//Mana renewal gives the player twice as much mana
			if (this.manaRenewal){
				differenceA = this.player_currentmana;
				this.player_currentmana = this.addHealth(this.player_currentmana, getPlayerMaxMana(), returnRenewalRate(true) * this.player_rank);
				differenceB = this.player_currentmana;
				if (differenceA!= differenceB){
					shroudAnimations.addAnimatedShroud((playerX+1)*constant, (playerY+1)*constant, 0);
				}
			}
			differenceA = this.player_currentmana;
			this.player_currentmana = this.addHealth(this.player_currentmana, getPlayerMaxMana(), returnRenewalRate(true) * this.player_rank);
			differenceB = this.player_currentmana;
			if (differenceA!= differenceB){
				shroudAnimations.addAnimatedShroud((playerX+1)*constant, (playerY+1)*constant, 0);
			}
		}
		this.tilesExplored++;
	}
	
	public boolean hasGoodEffects(){
		return (this.firstStrike()||(this.attackModifier != 0));
	}
	
	public boolean hasBadEffects(){
		return (this.manaBurn||this.poisoned||(this.weakness)||this.blinded||this.forget);
	}

	public int returnHUDAttack(){
		float lessAttack = 0;
		if(this.weakness){
			lessAttack = (float) -.25;
		}
		return (int) (this.permModifier + this.attackModifier+lessAttack+this.totalSightBonus + totemBonus);
	}
	
	public String returnGoodEffects(){
		String holder = "";
		DecimalFormat dec = new DecimalFormat("###.##");
		float lessAttack = 0;
		float benBonus = 0;
		if(this.weakness){
			lessAttack = (float) -.25;
		}
		
		if(this.hasGoodEffects()){
			benBonus = this.benefitsBonus;
		}
		if((this.permModifier + this.attackModifier+lessAttack+this.totalSightBonus+totemBonus) > 0){
			holder += "+" + dec.format((100 * (this.permModifier + this.attackModifier + lessAttack + this.totalSightBonus + totemBonus))) + "% Atk; ";
		}
		if(this.buildUpAttack > 0){
			holder += "+" + dec.format((100 * this.buildUpAttack)) + "% AtkSpree; ";
		}
		if(this.moreMagic > 0){
			holder += "+" + dec.format((100 * this.moreMagic)) + "% MgcAtk; ";
		}
		if(this.totalSightBonusHealth > 0 || (isShaman && totemBonus>0)){
			int healthupgrade = (int) this.totalSightBonusHealth;
			if(isShaman && totemBonus>0){
				healthupgrade += totemBonus * 40;
			}
			holder += "+" + healthupgrade + " HP; ";
		}
		if((isShaman && totemBonus>0)){
			holder += "+" + (int)(totemBonus * 40) + " MP; ";
		}
		if(this.physicalResistance > 0){
			holder += "+" + dec.format((100 * this.physicalResistance)) + "% pResist; ";
		}
		if(this.magicalResistance > 0){
			holder += "+" + dec.format((100 * this.magicalResistance)) + "% mResist; ";
		}
		if(this.dodgeRate != 0){
			holder += "+" + dec.format((100 * (this.dodgeRate + benBonus))) + "% evadRate; ";
		}
		if(this.gamblersLuck > 0 || this.cautiousLuck > 0){
			holder += "+" + dec.format((100 * (this.gamblersLuck + this.cautiousLuck))) + "% Lck; ";
		}
		if(this.deathGaze>0){
			holder += "+" + dec.format((100 * (this.deathGaze))) + "% DthGaze; ";
		}
		if(this.twiceHit > 0){
			holder += "+" + dec.format((100 * (this.twiceHit + benBonus))) + "% DblHit; ";
		}
		if (this.manaRenewal){
			holder += "HP->MP Regen; ";
		}
		if(this.attackPoisons){
			holder += "Poison Wpn; ";
		}
		if(this.bloodCollector && !this.extraLife){
			holder += "Blood (" + (int)this.bloodCollected + "/5); ";
		}
		if(this.extraLife){
			holder += "+1 Life; ";
		}
		if(this.firstStrike()){
			holder += "First Strike; ";
		}
		if (this.blindedImmun && this.weaknessImmun && this.forgetImmun && this.poisonedImmun && this.manaBurnImmun && this.sHUDImmun){
			holder += "Immune All; ";
		}
		else{
			if (this.blindedImmun){
				holder += "Blind ";
			}
			if (this.weaknessImmun){
				holder += "Weakness ";
			}
			if (this.forgetImmun){
				holder += "Amnesia ";
			}
			if (this.poisonedImmun){
				holder += "Poison ";
			}
			if (this.manaBurnImmun){
				holder += "ManaBurn ";
			}
			if (this.sHUDImmun){
				holder += "Static ";
			}
			if (this.banishImmune){
				holder += "Banish ";
			}
			if (this.blindedImmun || this.weaknessImmun || this.forgetImmun || this.poisonedImmun || this.manaBurnImmun || this.sHUDImmun || this.banishImmune){
				holder += "Immune; ";
			}
		}
		return holder;
	}
	
	public String returnBadEffects(){
		String holder = "";
		DecimalFormat dec = new DecimalFormat("###.##");
		float lessAttack = 0;
		if(this.weakness){
			lessAttack = (float) -.25;
		}
		if((this.permModifier+ this.attackModifier+lessAttack+this.totalSightBonus+totemBonus) < 0){
			holder += dec.format((100 * (this.permModifier+ this.attackModifier+lessAttack+this.totalSightBonus+totemBonus))) + "% Atk; ";
		}
		if(this.forget){
			holder += "-25% MagAtk; ";
		}
		if(this.physicalResistance < 0){
			holder += dec.format((100 * this.physicalResistance)) + "% pResist; ";
		}
		if(this.magicalResistance < 0){
			holder += dec.format((100 * this.magicalResistance)) + "% mResist; ";
		}
		if(this.manaBurn){
			holder += "mBurn; ";
		}
		if(this.poisoned){
			holder += "Poison; ";
		}
		if(this.blinded){
			holder += "10% MISS; ";
		}
		if(this.sHub){
			holder+= "Static; ";
		}
		if(this.gamblersLuck > 0){
			holder += "LowBound 70% Atk; ";
		}
		return holder;
	}
	
	public int returnMagicDamage(int baseDMG, ClassEnemyStats enemy, boolean prediction){
		int multiplier = 0;
		if (this.forget){
			multiplier+=.25;
		}
		if (enemy.MRnorm){
			multiplier+=.25;
		}
		if (enemy.MRplus){
			multiplier+=.50;
		}
		baseDMG = (int) ((baseDMG + (baseDMG * this.moreMagic))  * (1 - multiplier));
		if (baseDMG <= 0){baseDMG = 1;}
		if(!prediction){
			this.pDamageTotal += baseDMG;
			this.lastPlayerMagAttack = baseDMG;
			player_currentmana = addHealth(player_currentmana, player_mana, (int)(baseDMG * mgDmgRecovered));
		}
		return baseDMG;
	}
	
	public int returnMagicStats(){
		int baseDMG = 100;
		int multiplier = 0;
		if (this.forget){
			multiplier+=.25;
		}
		baseDMG = (int) ((baseDMG + (baseDMG * this.moreMagic))  * (1 - multiplier));
		return baseDMG;
	}
	
	public int playerCost(int glyphNumber){
		ClassGlyphActions gInfo= new ClassGlyphActions(); 
		int glyphCost;
		glyphCost = gInfo.returnCost(glyphNumber,this);
		glyphCost += this.costModifier;
		if (glyphCost< 1){glyphCost = 1;}
		if ((glyphNumber==0 || glyphNumber==1 || glyphNumber==16)){glyphCost = 0;}
		return glyphCost;
	}
	
	public int addHealth(int currenthealth, int maxhealth, int addhealth){
		currenthealth += addhealth;
		if(currenthealth > maxhealth){
			currenthealth = maxhealth;
		}
		if(currenthealth < 0){
			currenthealth = 0;
		}
		return currenthealth;
	}
	
	public ClassReferenceImage cowardMoves(ClassReferenceImage ref, PointF cursor){
		int newX = 0, newY = 0;
		boolean found = false;
		Random random = new Random(System.currentTimeMillis());
		while(!found){
		newX = random.nextInt( ref.tiles );
		newY = random.nextInt( ref.tiles );
			if ((ref.board.glyphPos[newX][newY] == 0) 
				&& (ref.board.enemyPos[newX][newY].returnMonster() == 0) 
				&& (ref.board.objPos[newX][newY] == 0) 
				&& (ref.map[newX][newY] == 0)
				&& (ref.board.shopPos[newX][newY].getItem() == 0)
				&& (ref.board.altarPos[newX][newY].getGod() == 0)
				&& ((ref.mapObject.getPlayerX() != newX) && (ref.mapObject.getPlayerY() != newY))){
				found = true;
			}
		}	
		ref.board.enemyPos[newX][newY] = ref.board.enemyPos[(int) cursor.x][(int) cursor.y];
		ref.board.enemyPos[(int) cursor.x][(int) cursor.y] = new ClassEnemyStats(0,0,0,0, false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
		return ref;
	}
	
	public PointF playerMoves(ClassReferenceImage ref){
		int newX = 0, newY = 0;
		boolean found = false;
		Random random = new Random(System.currentTimeMillis());

		while(!found){
			newX = random.nextInt( ref.tiles-2 )+1;
			newY = random.nextInt( ref.tiles-2 )+1;
			if ((ref.board.glyphPos[newX][newY] == 0) 
				&& (ref.board.enemyPos[newX][newY].returnMonster() == 0) 
				&& (ref.board.objPos[newX][newY] == 0) 
				&& (ref.map[newX][newY] == 0)
				&& (ref.board.shopPos[newX][newY].getItem() == 0)
				&& (ref.board.altarPos[newX][newY].getGod() == 0)
				&& ((ref.mapObject.getPlayerX() != newX) && (ref.mapObject.getPlayerY() != newY))){
				found = true;
			}
		}	
		return new PointF(newX,newY);
	}
	
    public void playSpellSounds (int Spell){
    	//1"Blood",
		//2"Converter",
		//3"Empty",
		//4"EndWall",
		//5"Fireball",
		//6"FirstStrike",
        //7"Grumpkin",
        //8"Heal",
        //9"KillProtect",
        //10"Might",
        //11"Petrify",
        //12"Poison",
        //13"Reveal",
        //14"Summon",
        //15"TeleMonster",
        //16"ManaSpark"
		//17 Totem
		//18 Klondike
		switch(Spell){
			case 1:
				sounds.playSound(2);
				break;
			case 2:
				sounds.playSound(3);
				break;
			case 3:
				sounds.playSound(1);
				break;
			case 4:
				sounds.playSound(4);
				break;
			case 5:
				sounds.playSound(1);
				break;
			case 6:
				sounds.playSound(2);
				break;
			case 7:
				sounds.playSound(2);
				break;
			case 8:
				sounds.playSound(4);
				break;
			case 9:
				sounds.playSound(2);
				break;
			case 10:
				sounds.playSound(1);
				break;
			case 11:
				sounds.playSound(1);
				break;
			case 12:
				sounds.playSound(3);
				break;
			case 13:
				sounds.playSound(2);
				break;
			case 14:
				sounds.playSound(4);
				break;
			case 15:
				sounds.playSound(3);
				break;
			case 16:
				sounds.playSound(4);
				break;
			case 17:
				sounds.playSound(1);
				break;
			case 18:
				sounds.playSound(1);
				break;
			default:break;
		}
    }
    
    public void manaBleed(){
    	this.player_currenthealth = this.addHealth(player_currenthealth, player_health, (int)(((float)player_health)*((float)manaBleed)));
		if(player_currenthealth <=0){
			player_currenthealth = 1;
		}
    }
    
	public ClassReferenceImage useSpell(int glyph, ClassReferenceImage ref, int cursorX, int cursorY){
		int newX, newY, count;
		boolean found;
		Random random = new Random(System.currentTimeMillis());
		this.lastPlayerMagAttack = 0;
		int cost = playerCost(glyph);
		//System.out.println(cost);
		//System.out.println(glyph);
		if(player_currentmana >= cost){
			player_currentmana -= cost;
			if(this.manaHeal){
				manaHealFunction(cost,glyph);
			}
			playSpellSounds(glyph);
			switch(glyph){
				case 1:
					//Regen to mana instead of health
					//Switches mana renewal on or off
					//This spell has no cost
					this.manaRenewal = !this.manaRenewal;
					this.spellsUsed[glyph-1]++;
					pietyActions(11);
					return ref;
				case 2:
					//Converter
					if (this.player_gold >= 5 && (this.player_currenthealth != getPlayerMaxHealth() || 
					this.poisoned || this.blinded || this.forget || this.manaBurn || this.weakness || this.sHub)){
						this.player_gold -= 5;
						pietyActions(7);
						this.player_currenthealth += this.player_rank * 5;
						this.manaBurn = false;
						this.poisoned = false;
						this.blinded = false;
						this.forget = false;
						this.weakness = false;
						this.sHub = false;
						this.spellsUsed[glyph-1]++;
						pietyActions(11);
						if (this.player_currenthealth > getPlayerMaxHealth()){
							this.player_currenthealth = getPlayerMaxHealth();
						}
						manaBleed();
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 3:
					//This is where the blank tile is. Nothing should be here
					//this.spellsUsed[glyph-1]++;
					return ref;
				case 4:
					//Destroy wall section
					if (ref.map[cursorX][cursorY] == 1){
						pietyActions(10);
						ref.map[cursorX][cursorY] = 0;
						ref.setDebrisObj(cursorX, cursorY, 0);
						spellsUsed[glyph-1]++;
						pietyActions(11);
						player_currenthealth = addHealth(player_currenthealth, getPlayerMaxHealth(), wallDestructBonus);
						player_gold += minerBonus;
						manaBleed();
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 5:
					//Fireball
					if (ref.enemyNum(cursorX,cursorY) != 0){
						manaBleed();
						ref.returnEnemyObj(cursorX,cursorY).currentHealth -= returnMagicDamage(4*this.player_rank,ref.returnEnemyObj(cursorX,cursorY),false);
						this.spellsUsed[glyph-1]++;
						pietyActions(11);
						if (ref.returnEnemyObj(cursorX,cursorY).currentHealth <= 0 && ref.returnEnemyObj(cursorX, cursorY).extraLives<2){
							killCalc(ref.returnEnemyObj(cursorX,cursorY).returnLevel(), ref.returnEnemyObj(cursorX,cursorY).undead, ref.returnEnemyObj(cursorX,cursorY).magicAttack);
							ref.board.enemyPos[cursorX][cursorY] = new ClassEnemyStats(0,0,0,0, false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
						}else if (ref.returnEnemyObj(cursorX,cursorY).currentHealth <= 0 && ref.returnEnemyObj(cursorX, cursorY).extraLives>=2){
							ref.returnEnemyObj(cursorX, cursorY).extraLives--;
							ref.returnEnemyObj(cursorX, cursorY).currentHealth = 1;
						}
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					
					return ref;
				case 6:
					//First Strike
					if(!this.strikeModifier){
						manaBleed();
						pietyActions(7);
						pietyActions(11);
						this.strikeModifier = true;
						if (this.benefitsPoison){
							this.poisoned = true;
						}
						this.spellsUsed[glyph-1]++;
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 7:
					//Turn blood pool into grumpkin
					if (ref.debrisNum(cursorX,cursorY) == 1){
						manaBleed();
						this.pietyActions(16);
						pietyActions(11);
						ref.board.enemyPos[cursorX][cursorY] = 
								new ClassEnemyStats(Draws.enemyBaseStats[17][0],
								Draws.enemyBaseStats[17][1],
								Draws.enemyBaseStats[17][2],
								18,
								Draws.enemyAbilityStats[17][0], 
								Draws.enemyAbilityStats[17][1], 
								Draws.enemyAbilityStats[17][2], 
								Draws.enemyAbilityStats[17][3], 
								Draws.enemyAbilityStats[17][4], 
								Draws.enemyAbilityStats[17][5],
								Draws.enemyAbilityStats[17][6],
								Draws.enemyAbilityStats[17][7],
								Draws.enemyAbilityStats[17][8],
								Draws.enemyAbilityStats[17][9],
								Draws.enemyAbilityStats[17][10],
								Draws.enemyAbilityStats[17][11],
								Draws.enemyAbilityStats[17][12],
								Draws.enemyAbilityStats[17][13],
								Draws.enemyAbilityStats[17][14]);
						ref.returnEnemyObj(cursorX, cursorY).setLevel(grumpkinLevel);
						ref.setDebrisObj(cursorX, cursorY, 0);
						this.spellsUsed[glyph-1]++;
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 8:
					//Healing Spell
					if (this.player_currenthealth != getPlayerMaxHealth() || this.poisoned || this.blinded || this.weakness){
						manaBleed();
						this.spellsUsed[glyph-1]++;
						pietyActions(7);
						pietyActions(11);
						this.player_currenthealth += this.player_rank * 3;
						this.poisoned = false;
						this.blinded = false;
						this.weakness = false;
						if (this.player_currenthealth > this.getPlayerMaxHealth()){
							this.player_currenthealth = this.getPlayerMaxHealth();
					}
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 9:
					//Protected from next killing blow
					if(!extraLife){
						manaBleed();
						pietyActions(7);
						pietyActions(11);
						extraLife = true;
						this.spellsUsed[glyph-1]++;
						if (this.benefitsPoison){
							this.poisoned = true;
						}
					}
					else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 10:
					//Might Spell
					if (this.attackModifier == 0){
						manaBleed();
						pietyActions(7);
						pietyActions(11);
						this.attackModifier = (float) .30;
						if (this.benefitsPoison){
							this.poisoned = true;
						}
						this.spellsUsed[glyph-1]++;
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 11:
					//Turns Enemy Into Wall
					if((ref.enemyNum(cursorX,cursorY) != 0) 
							&& (ref.returnEnemyObj(cursorX, cursorY).level <= 8 || this.superPetrify)){
						manaBleed();
						ref.board.enemyPos[cursorX][cursorY] = new ClassEnemyStats(0,0,0,0, false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
						ref.map[cursorX][cursorY] = 1;
						this.spellsUsed[glyph-1]++;
						petraKill++;
						pietyActions(9);
						pietyActions(11);
						addEXP(ref.returnEnemyObj(cursorX,cursorY).level);
						player_health += wallCreateBonus;
						//player_currenthealth = addHealth(player_currenthealth, getPlayerMaxHealth(), wallCreateBonus);
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 12:
					//Inflicts poison on monster
					if (this.attackPoisons == false){
						manaBleed();
						this.attackPoisons = true;
						this.spellsUsed[glyph-1]++;
						pietyActions(11);
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					
					return ref;
				case 13:
					//Reveals 3 unexplored tiles
					newX = 0; newY = 0; count = 0;
					//count number of shroud
					
					
					this.spellsUsed[glyph-1]++;
					pietyActions(11);
					if(ref.countShroudTiles()>2){
						manaBleed();
						while(count < 3){
							newX = random.nextInt( ref.tiles );
							newY = random.nextInt( ref.tiles );
							if (ref.shroudNum(newX, newY) != 0){
								ref.setShroudObj(newX,newY,0);
								shroudRenewal(newX,newY);
								count++;
							}
						}
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}

					return ref;
				case 14:
					int enemyX = -1, enemyY = -1;
					int playerPx, playerPy;
					//Summons monster at same lvl
					//Search the map for a monster at the same lvl
					for(int y = 0; y < ref.tiles; y++){
						for(int x = 0; x < ref.tiles; x++){
							if((ref.board.enemyPos[x][y].returnMonster() != 0) && (ref.board.enemyPos[x][y].level == this.player_rank)){
								//found enemy
								enemyX = x;
								enemyY = y;
								break;
							}
						}
					}
					//Search around hero for empty space
					//Put monster in first empty space found
					if (enemyX != -1 && enemyY != -1){
						playerPx = ref.mapObject.getPlayerX();
						playerPy = ref.mapObject.getPlayerY();
							if ((playerPx != 0) && (ref.board.glyphPos[playerPx-1][playerPy] == 0) 
								&& (ref.board.enemyPos[playerPx-1][playerPy].returnMonster() == 0) 
								&& (ref.board.objPos[playerPx-1][playerPy] == 0) 
								&& (ref.map[playerPx-1][playerPy] == 0)){
								manaBleed();
								ref.board.enemyPos[playerPx-1][playerPy] = ref.board.enemyPos[enemyX][enemyY];
								ref.board.enemyPos[enemyX][enemyY] = new ClassEnemyStats(0,0,0,0, false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
								this.spellsUsed[glyph-1]++;
								pietyActions(11);
							}else if((playerPx < ref.tiles) && (ref.board.glyphPos[playerPx+1][playerPy] == 0) 
									&& (ref.board.enemyPos[playerPx+1][playerPy].returnMonster() == 0) 
									&& (ref.board.objPos[playerPx+1][playerPy] == 0) 
									&& (ref.map[playerPx+1][playerPy] == 0)){
								manaBleed();
								ref.board.enemyPos[playerPx+1][playerPy] = ref.board.enemyPos[enemyX][enemyY];
								ref.board.enemyPos[enemyX][enemyY] = new ClassEnemyStats(0,0,0,0, false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
								this.spellsUsed[glyph-1]++;
								pietyActions(11);
							}else if((playerPy != 0) && (ref.board.glyphPos[playerPx][playerPy-1] == 0) 
									&& (ref.board.enemyPos[playerPx][playerPy-1].returnMonster() == 0) 
									&& (ref.board.objPos[playerPx][playerPy-1] == 0) 
									&& (ref.map[playerPx][playerPy-1] == 0)){
								manaBleed();
								ref.board.enemyPos[playerPx][playerPy-1] = ref.board.enemyPos[enemyX][enemyY];
								ref.board.enemyPos[enemyX][enemyY] = new ClassEnemyStats(0,0,0,0, false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
								this.spellsUsed[glyph-1]++;
								pietyActions(11);
							}else if((playerPy < ref.tiles) && (ref.board.glyphPos[playerPx][playerPy+1] == 0) 
									&& (ref.board.enemyPos[playerPx][playerPy+1].returnMonster() == 0) 
									&& (ref.board.objPos[playerPx][playerPy+1] == 0) 
									&& (ref.map[playerPx][playerPy+1] == 0)){
								manaBleed();
								ref.board.enemyPos[playerPx][playerPy+1] = ref.board.enemyPos[enemyX][enemyY];
								ref.board.enemyPos[enemyX][enemyY] = new ClassEnemyStats(0,0,0,0, false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
								this.spellsUsed[glyph-1]++;
								pietyActions(11);
							}
							//The player is surrounded by obstacles
							//give back mana
							else if(!this.manaHeal){
								player_currentmana += cost;
							}
					}
					else if(!this.manaHeal){
						//no monster at same level found
						player_currentmana += cost;
					}
					return ref;
				case 15:
					//Teleports monster to random tile
					newX = 0; newY = 0;
					found = false;
					
					if(ref.enemyNum(cursorX,cursorY) != 0){
						manaBleed();
						this.spellsUsed[glyph-1]++;
						pietyActions(11);
					while(!found){
						newX = random.nextInt( ref.tiles );
						newY = random.nextInt( ref.tiles );
						if ((ref.board.glyphPos[newX][newY] == 0) 
								&& (ref.board.enemyPos[newX][newY].returnMonster() == 0) 
								&& (ref.board.objPos[newX][newY] == 0) 
								&& (ref.map[newX][newY] == 0)
								&& (ref.board.shopPos[newX][newY].getItem() == 0)
								&& (ref.board.altarPos[newX][newY].getGod() == 0)
							&& ((ref.mapObject.getPlayerX() != newX) && (ref.mapObject.getPlayerY() != newY))){
								found = true;
						}
					}	
						ref.board.enemyPos[newX][newY] = ref.board.enemyPos[cursorX][cursorY];
						ref.board.enemyPos[cursorX][cursorY] = new ClassEnemyStats(0,0,0,0, false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
						if(this.alienTeleport){
							ref.returnEnemyObj(newX, newY).ePoisoned = true;
						}
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 16:
					//Does damage equal to player's current mana reserve. Drains half mana
					if (ref.enemyNum(cursorX,cursorY) != 0 && player_currentmana > 0){
						manaBleed();
						ref.returnEnemyObj(cursorX,cursorY).currentHealth -= returnMagicDamage(this.player_currentmana,ref.returnEnemyObj(cursorX,cursorY),false);
						this.spellsUsed[glyph-1]++;
						pietyActions(11);
						if(!manaSparkHalf){
							this.player_currentmana /= 2;
						}else{
							this.player_currentmana /= 4;
						}
						if (ref.returnEnemyObj(cursorX,cursorY).currentHealth <= 0){
							if(ref.returnEnemyObj(cursorX,cursorY).extraLives<2){
								killCalc(ref.returnEnemyObj(cursorX,cursorY).returnLevel(),ref.returnEnemyObj(cursorX,cursorY).undead, ref.returnEnemyObj(cursorX,cursorY).magicAttack);
								ref.board.enemyPos[cursorX][cursorY] = new ClassEnemyStats(0,0,0,0, false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
							}else{
								ref.returnEnemyObj(cursorX,cursorY).extraLives--;
								ref.returnEnemyObj(cursorX,cursorY).currentHealth = 1;
							}
						}
					}
					//Since this spell has no cost, nothing to give back
					return ref;
				case 17:
					//Totem glyph
					if (ref.debrisNum(cursorX,cursorY) == 1 
					&& !((ref.mapObject.getPlayerX() == cursorX && ref.mapObject.getPlayerY() == cursorY))){
						manaBleed();
						this.pietyActions(16);
						ref.map[cursorX][cursorY] = 1;
						ref.setDebrisObj(cursorX, cursorY, 2);
						this.spellsUsed[glyph-1]++;
						pietyActions(11);
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 18:
					//Klondike glyph
					if (ref.enemyNum(cursorX,cursorY) != 0){
						manaBleed();
						ref.returnEnemyObj(cursorX,cursorY).currentHealth -= returnMagicDamage(this.player_gold/4,ref.returnEnemyObj(cursorX,cursorY),false);
						this.spellsUsed[glyph-1]++;
						pietyActions(11);
						if (ref.returnEnemyObj(cursorX,cursorY).currentHealth <= 0){
							if(ref.returnEnemyObj(cursorX,cursorY).extraLives<2){
								killCalc(ref.returnEnemyObj(cursorX,cursorY).returnLevel(),ref.returnEnemyObj(cursorX,cursorY).undead, ref.returnEnemyObj(cursorX,cursorY).magicAttack);
								ref.board.enemyPos[cursorX][cursorY] = new ClassEnemyStats(0,0,0,0, false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
							}else{
								ref.returnEnemyObj(cursorX,cursorY).extraLives--;
								ref.returnEnemyObj(cursorX,cursorY).currentHealth = 1;
							}
						}
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 19:
					//Nexus glyph
					if (ref.enemyNum(cursorX,cursorY) != 0){
						manaBleed();
						ref.returnEnemyObj(cursorX,cursorY).currentHealth -= returnMagicDamage(findEnemies(ref),ref.returnEnemyObj(cursorX,cursorY),false);
						this.spellsUsed[glyph-1]++;
						pietyActions(11);
						if (ref.returnEnemyObj(cursorX,cursorY).currentHealth <= 0){
							if(ref.returnEnemyObj(cursorX,cursorY).extraLives<2){
								killCalc(ref.returnEnemyObj(cursorX,cursorY).returnLevel(),ref.returnEnemyObj(cursorX,cursorY).undead, ref.returnEnemyObj(cursorX,cursorY).magicAttack);
								ref.board.enemyPos[cursorX][cursorY] = new ClassEnemyStats(0,0,0,0, false, false, false, false, false, false, false, false, false, false,false, false, false, false,false);
							}else{
								ref.returnEnemyObj(cursorX,cursorY).extraLives--;
								ref.returnEnemyObj(cursorX,cursorY).currentHealth = 1;
							}
						}
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				case 20:
					//Affinity glyph
					if (ref.debrisNum(cursorX,cursorY) == 1 
					&& !((ref.mapObject.getPlayerX() == cursorX && ref.mapObject.getPlayerY() == cursorY))){
						manaBleed();
						this.pietyActions(16);
						pietyActions(11);
						//ref.map[cursorX][cursorY] = 1;
						ref.setDebrisObj(cursorX, cursorY, 0);
						int pick = random.nextInt( 20 );
						if(pick == 0){
							if(specialShops){
								ref.board.shopPos[cursorX][cursorY] = new ClassShop(7,23);
							}
						else if(pick == 1){
							if(specialShops){
								ref.board.shopPos[cursorX][cursorY] = new ClassShop(15,24);
							}	
						}
						}else if(pick <5){
							ref.board.objPos[cursorX][cursorY] = 1;
						}else if(pick <9){
							ref.board.objPos[cursorX][cursorY] = 2;
						}else if(pick < 13){
							ref.board.objPos[cursorX][cursorY] = 4;
						}else if(pick < 17){
							ref.board.objPos[cursorX][cursorY] = 6;
						}else if(pick == 17){
							ref.board.shopPos[cursorX][cursorY] = new ClassShop(5,20);
						}else if(pick == 18){
								ref.board.shopPos[cursorX][cursorY] = new ClassShop(5,21);
						}else{
							ref.board.shopPos[cursorX][cursorY] = new ClassShop(5,22);
						}
						this.spellsUsed[glyph-1]++;
					}else if(!this.manaHeal){
						player_currentmana += cost;
					}
					return ref;
				default:return ref;
			}
		}
		return ref;
	}

	public int findEnemies(ClassReferenceImage ref){
		int damage = 0;
		for(int y = 0; y < ref.tiles; y++){
			for(int x = 0; x < ref.tiles; x++){
				if(ref.enemyNum(x,y) != 0){
					damage += 1.5;
				}
			}
		}
		return damage;
	}
	
	public void manaHealFunction(int cost, int glyph){
		player_currenthealth += cost * 1.5;
		if(glyph == 16){
			player_currenthealth += player_currentmana;
		}
		if (player_currenthealth > getPlayerMaxHealth()){
			player_currenthealth = getPlayerMaxHealth();
		}
	}
	/*public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}

	public void writeToParcel(Parcel dest, int flags) {
		dest.writeInt(constant);
		dest.writeInt(player_race);
		dest.writeInt(player_class);
		dest.writeInt(player_level);
		dest.writeIntArray(backupData);
	}
	
	public static final Parcelable.Creator<gameStats> CREATOR = new Parcelable.Creator<gameStats>() {
        public gameStats createFromParcel(Parcel in) {
            return new gameStats(in);
        }

        public gameStats[] newArray(int size) {
            return new gameStats[size];
        }
    };

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private gameStats(Parcel in) {
    	constant = in.readInt();
    	player_race = in.readInt();
    	player_class = in.readInt();
    	player_level = in.readInt();
    	in.readIntArray(backupData);

    }*/
	
}
